import { login, logout, getPermissions } from '@/api/system/user';
import { getToken, setToken, removeToken } from '@/utils/auth';
import router, { resetRouter } from '@/router';
import { dictCache, refresh } from '@/api/system/dict';
import Cookies from 'js-cookie';

const getDefaultState = () => {
	return {
		token: getToken(),
		name: '',
		avatar: '',
		currentUser: {},
		dict: []
	};
};

const state = getDefaultState();

const mutations = {
	RESET_STATE: (state) => {
		Object.assign(state, getDefaultState());
	},
	SET_TOKEN: (state, token) => {
		state.token = token;
	},
	SET_NAME: (state, name) => {
		state.name = name;
	},
	SET_AVATAR: (state, avatar) => {
		state.avatar = avatar;
	},
	setCurrentUser: (state, currentUser) => {
		state.currentUser = currentUser;
	},
	setDict: (state, dict) => {
		state.dict = dict;
	}
};

const actions = {
	login({ commit }, userInfo) {
		const { name, password } = userInfo;
		return new Promise((resolve, reject) => {
			login({ name: name.trim(), password: password })
				.then((response) => {
					commit('SET_TOKEN', response.access);
					commit('setCurrentUser', {
						id: response.userId,
						name: name.trim(),
						userName: response.userName,
						menus: response.menus,
						permissions: response.permissions
					});
					sessionStorage.setItem('permissions', JSON.stringify(response.permissions));
					setToken(response.access);
					Cookies.set('token', response.access);
					handleRouters(response.menus, router);
					resolve();
				})
				.catch((error) => {
					reject(error);
				});
		});
	},
	async dictInfo({ commit }) {
		return new Promise((resolve, reject) => {
			dictCache()
				.then((res) => {
					commit('setDict', res);
					resolve();
				})
				.catch((error) => {
					reject(error);
				});
		});
	},
	async refresh({ commit }) {
		return new Promise((resolve, reject) => {
			refresh()
				.then((res) => {
					commit('setDict', res.data);
					resolve();
				})
				.catch((error) => {
					reject(error);
				});
		});
	},
	async getPermissionsByToken({ commit }) {
		return new Promise((resolve, reject) => {
			if (!localStorage.getItem('token')) {
				setTimeout(() => {
					router.push('/');
				}, 2000);
				return reject('无token');
			}
			getPermissions()
				.then(async (response) => {
					commit('SET_TOKEN', localStorage.getItem('token'));
					commit('setCurrentUser', {
						id: response.userInfo.id,
						name: response.userInfo.name,
						userName: response.userInfo.userName,
						menus: response.menus,
						permissions: response.permissions
					});
					dictCache()
						.then((res) => {
							commit('setDict', res);
							resolve();
						})
						.catch((error) => {
							reject(error);
						});
					sessionStorage.setItem('permissions', JSON.stringify(response.permissions));
					handleRouters(response.menus, router);
					resolve();
				})
				.catch((error) => {
					reject(error);
				});
		});
	},
	logout({ commit }) {
		return new Promise((resolve, reject) => {
			logout()
				.then(() => {
					removeToken();
					resetRouter();
					commit('RESET_STATE');
					sessionStorage.removeItem('permissions');
					Cookies.remove('token');
					resolve();
				})
				.catch((error) => {
					reject(error);
				});
		});
	},
	resetToken({ commit }) {
		return new Promise((resolve) => {
			removeToken();
			commit('RESET_STATE');
			resolve();
		});
	}
};

function handleRouters(menus, router) {
	router.options.routes.forEach((e) => {
		if (e.meta.white == null || e.meta.white == false) {
			let menu = menus.find((ee) => ee.url&&( ee.url === e.path || ee.url.indexOf(e.path) !== -1));
			if (!menu) {
				e.meta.auth = 'false';
			} else {
				e.meta.auth = 'true';
			}
			if (e.children && e.children.length) {
				handleRecursion(menus, e.children);
			}
		}
	});
}

function handleRecursion(menus, childRoutes) {
	childRoutes.forEach((e) => {
		let menu = menus.find((ee) => ee.url&&(ee.url === e.path || ee.url.indexOf(e.path) !== -1));
		if (!menu) {
			e.meta.auth = 'false';
		} else {
			e.meta.auth = 'true';
		}
		if (e.children && e.children.length) {
			handleRecursion(menus, e.children);
		}
	});
}

export default {
	namespaced: true,
	state,
	mutations,
	actions
};
